package com.treeroot.linkedlist;

/**
 * 定义 SingleLinkedList 管理 HeroNode
 */
public class HeroNodeByGPT {
    // 1. 初始化头结点 【不要动】不存放具体的数据，用于索引下面的对象
    private HeroNode head = new HeroNode(0, "", "");

    /**
     * 添加节点到单向链表
     *
     * @param heroNode 待添加的节点
     */
    public void add(HeroNode heroNode) {
        // 1. 当不考虑编号顺序时
        // 2. 找到当前链表的最后一个节点
        // 因为 head 节点不能动，因此我们需要一个辅助变量 temp
        // temp 指向 head 节点对象地址，数据共享存入 head 地址中
        HeroNode temp = head;
        // 遍历链表找到最后一个节点
        while (true) {
            if (temp.next == null) {
                break;
            }
            // 没有找到就将 temp 设为最后一个节点
            temp = temp.next;
        }
        // 当退出 while 循环时，temp 就指向了链表的最后
        // 将最后这个节点的 next 指向新的节点
        temp.next = heroNode;
    }

    /**
     * 添加节点到单向链表，并按照节点的编号顺序进行排序
     *
     * @param heroNode 待添加的节点
     */
    public void addPlus(HeroNode heroNode) {
        // 因为头结点不能动，通过辅助指针 temp 找到添加的位置
        // 因为是单链表，找到是 temp 的前一个节点，如果没有 no 字段的话是无法插入的
        HeroNode temp = head;
        // 添加编号的标识，no 字段是否存在，默认为 false
        boolean flag = false;
        while (temp.next != null) {
            // 如果当前的节点编号在要输入的节点编号前，则插入到 temp 的后面
            if (temp.next.no > heroNode.no) {
                break;
            }
            // 如果希望添加的节点的编号已经存在，则不能添加
            else if (temp.next.no == heroNode.no) {
                flag = true;
                break;
            }
            // 不符合以上条件==>后移 temp，继续遍历链表
            temp = temp.next;
        }
        //根据标识 flag 判断是否可以插入节点
        if (flag) {
            System.out.println("准备插入的节点的编号已存在，无法继续加入");
        } else {
            // 插入到链表中，temp 的后面
            heroNode.next = temp.next;
            temp.next = heroNode;
        }
    }

    /**
     * 显示链表
     */
    public void list() {
        // 判断链表是否为空
        if (head.next == null) {
            System.out.println("链表为空");
            return;
        }
        // 因为 head 节点不能动，因此我们需要一个辅助变量 temp
        HeroNode temp = head.next;
        // 遍历得到数据
        while (temp != null) {
            // 输出节点信息
            System.out.println(temp);
            // 将 temp 后移
            temp = temp.next;
        }
    }

    /**
     * 修改单节点的信息，根据单节点的 no 字段修改
     *
     * @param newHeroNode 新的节点
     */
    public void update(HeroNode newHeroNode) {
        // 判断是否为空
        if (head.next == null) {
            System.out.println("链表为空");
            return;
        }
        // 找到需要修改的节点
        HeroNode temp = head.next;
        // 是否找到了 no 字段
        boolean flag = false;
        while (temp != null) {
            // 已经找到了
            if (temp.no == newHeroNode.no) {
                flag = true;
                break;
            }
            temp = temp.next;
        }
        // 根据 flag 判断是否找到需要修改的节点
        if (flag) {
            temp.name = newHeroNode.name;
            temp.NickName = newHeroNode.NickName;
        } else {
            System.out.println("【异常数据】没有相应编号的节点");
        }
    }

    /**
     * 删除某个子节点
     *
     * @param no 待删除节点的编号
     */
    public void delete(int no) {
        HeroNode temp = head;
        // 找到被删除的节点的前一个节点
        // 表示是否找到找到被删除的节点的前一个节点
        boolean flag = false;
        while (temp.next != null) {
            // 找到了待删除节点的前一个节点
            if (temp.next.no == no) {
                flag = true;
                break;
            }
            // temp 后移继续循环查找
            temp = temp.next;
        }
        if (flag) {
            // 进行删除
            temp.next = temp.next.next;
        } else {
            System.out.println("【异常数据】不存在被删除的节点");
        }
    }
}
